package com.dji.ux.sample.Weather;



public class WeatherUtils {


     //机柜询问帧的格式如下，直接复制即可使用；
     public static byte[] get_weather = {
           0x50,0x00,//5000是3E帧识别帧头，4E帧是5400
           0x00,//网路编号，上位访问下位，固定00；
           (byte) 0xff,//PLC编号，上位访问下位，固定FF;
           (byte) 0xff,0x03,//请求目标模块IO编号，值要从小到大看，也就是反过来看，三菱所有的协值都是这样，所以这里是03FF,十进制是1023； 也是固定的；
           0x00,//请求目标模块站编号，上位访问下位，固定00;
           0x0c,0x00,//命令内容的长度，从这两个字节之后的数据的字节数
           0x10,0x00,//表示等待PLC响应的timeout时间；这里 值是0010，十进制是16 ；相当与最大等待时间250ms*16=4秒；实际上PLC一般2,3个毫秒内就响应了；
           0x01,0x04,//主命令，值是0401(所有值都要反过来看，)；表示批量读取；如果是1401就是随机读取；
           0x00,0x00,//子命令，值是0表示按字读取(1个字=16位),如果值是1就按位读取；
           (byte)0xFE,0x01,0x00,//地址因为跨度比较大，所以用了3个字节；这里的值是000064，十进制就是100
           (byte) 0xa8,//表示读取PLC寄存器的类型： 这里的A8表示D点；其他常见的有： 90-M点；9C-X点；9D-Y点；B0-ZR外部存储卡
           (byte) 0x35,0x00};//读取长度，值是0014，十进制就是2；


    /**
     * 解析气象站应答帧，并封装成对象
     * @param bytes  响应回来的字节数组；
     * @param offset 数据段在应答帧中的偏移,单位字节,为Null则任务是10
     * @return WeatherParams
     * @author 王春露
     */
    public static WeatherParams bytesToStatus(byte[] bytes,Integer offset){

        //三棱的应答字节数组的 数据区域 是第10个字节开始的。
        int OFFSET = 10;
        if(offset!=null){OFFSET = offset;}

        // 指标 偏移 系数
        //风速 0 0.1
        double windSpeed = 0.1*toUnsignedInt(bytes[1 + OFFSET], bytes[OFFSET]);
        //风力 1 1
        int windPower = toUnsignedInt(bytes[3 + OFFSET], bytes[2+OFFSET]);
        //风向 2 1
        int windDirection = toUnsignedInt(bytes[5 + OFFSET], bytes[4+OFFSET]);
        //土壤1湿度 4 0.1
        double MudWater = 0.1*toUnsignedInt(bytes[9 + OFFSET], bytes[8+OFFSET]);
        //土壤1温度 5 0.1
        double MudTemperature = 0.1*toUnsignedInt(bytes[11 + OFFSET], bytes[10+OFFSET]);
        //土壤1EC 6 1
        int MudEC = toUnsignedInt(bytes[13 + OFFSET], bytes[12+OFFSET]);
        //土壤1PH 7 0.1
        double MudPH = 0.1*toUnsignedInt(bytes[15 + OFFSET], bytes[14+OFFSET]);
        //空气湿度 20 0.1
        double  airWater = 0.1*toUnsignedInt(bytes[41 + OFFSET], bytes[40+OFFSET]);
        //空气温度 21 0.1
        double airTemperature = 0.1*toUnsignedInt(bytes[43 + OFFSET], bytes[42+OFFSET]);
        //大气压 24 0.1
        double pressure = 0.1*toUnsignedInt(bytes[49 + OFFSET], bytes[48+OFFSET]);
        //累计雨量（气象站启动至今）31 0.2
        long rainfallAll = toUnsignedLong(bytes[65 + OFFSET],bytes[64 + OFFSET],bytes[63 + OFFSET], bytes[62+OFFSET]);
        //当前雨量（00：00 到现在的雨量）33 0.2
        double rainfallNowDay = 0.2*toUnsignedInt(bytes[67 + OFFSET], bytes[66+OFFSET]);
        //瞬时雨量（一分钟前到现在的雨量）34 0.2
        double rainfallNowMinute = 0.2*toUnsignedInt(bytes[69 + OFFSET], bytes[68+OFFSET]);
        //日雨量（昨天一天的雨量） 35 0.2
        double rainfallYesterday = 0.2*toUnsignedInt(bytes[71 + OFFSET], bytes[70+OFFSET]);

        final WeatherParams params = new WeatherParams(windSpeed,windPower,windDirection,MudWater,MudTemperature,MudEC
                ,MudPH,airWater,airTemperature,pressure,rainfallAll,rainfallNowDay,rainfallNowMinute,rainfallYesterday);

        return params;
    }

    /**
     * 字节数组转 BCD 十六进制（测试使用）
     * @param b
     * @return String 两位16进制的字符串
     * @author 王春露
     */
    public static String bytes2HexString(byte[] b) {
        String r = "";
        for (int i = 0; i < b.length; i++) {
            String hex = Integer.toHexString(b[i] & 0xFF);
            if (hex.length() == 1) {
                hex = '0' + hex;
            }
            r += hex.toUpperCase()+" ";
        }
        return r;
    }
    /**
     * 低八位字节+高八位字节 转无符号Int
     * @param high
     * @param low
     * @author 王春露
     * @return int
     */
    private static int toUnsignedInt(byte high,byte low){
        int highInt =  high&0xff;
        int lowInt =  low&0xff;
        int result = (highInt<<8)|lowInt;
        return result&0xffff;

    }
    /**
     * 从低位到高位，四个字节，转无符号Long
     * @param b0 最高八位
     * @param b1 中高八位
     * @param b2 中低八位
     * @param b3 最低八位
     * @author 王春露
     * @return long
     */
    private static long toUnsignedLong(byte b0,byte b1,byte b2,byte b3){
        return ((long)(b3 & 0xff) << 24)
                | ((b2 & 0xff) << 16)
                | ((b1 & 0xff) << 8)
                | (b0 & 0xff);
    }
    /**
     * 字节转无符号Int
     * @param b
     * @author 王春露
     * @return int
     */
    private static int byteToUnsignedInt(byte b){
        return b & 0xff;
    }
    private  WeatherUtils(){}
}
